package Validator;

import com.carpark.ejb.Model.AccountingdataModel;
import com.carpark.ejb.Model.CarsModel;
import com.carpark.ejb.Model.ClientsModel;
import com.carpark.ejb.Model.EmployeesModel;
import com.carpark.ejb.Model.ParkingpassesModel;
import com.carpark.ejb.Model.ParkingspacesModel;
import com.carpark.ejb.Model.ParksModel;
import com.carpark.ejb.Model.PassesrecordsModel;
import com.carpark.ejb.Model.PaymentsModel;
import com.carpark.ejb.Model.ReceivablesModel;
import com.carpark.ejb.Model.ServicesModel;
import com.carpark.ejb.Model.TarrifsModel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 *
 * @author Sawior
 */
public class Validator {

    private static final String EMAIL_PATTERN =
            "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
            + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    private static Pattern pattern;
    private static Matcher matcher;

    public static boolean checkEmloyee(EmployeesModel employee) {
        if (checkNull(employee)) {
            return false;
        }
        return checkString(employee.getSurname(), 50)
                && checkString(employee.getFirstname(), 20)
                && checkString(employee.getJobType(), 255)
                && checkPesel(employee.getPeselNumber())
                && checkString(employee.getCity(), 30)
                && checkString(employee.getZipCode(), 15)
                && checkString(employee.getStreet(), 30)
                && checkString(employee.getHouseNumber(), 5)
                && checkIntNotNeeded(employee.getLocalNumber(), 11)
                && checkDate(employee.getEmploymentDate())
                && checkStringNotNeeded(employee.getPhone(), 12)
                && checkSalary(employee.getSalary())
                && checkStringNotNeeded(employee.getComments(), 100);
    }

    public static boolean checkClient(ClientsModel client) {
        if (checkNull(client)) {
            return false;
        }
        return checkString(client.getName(), 20)
                && checkString(client.getLastName(), 50)
                && checkString(client.getCity(), 30)
                && checkString(client.getZipCode(), 15)
                && checkString(client.getStreet(), 30)
                && checkString(client.getHouseNumber(), 15)
                && checkIntNotNeeded(client.getLocalNumber(), 11)
                && checkStringNotNeeded(client.getNipNumber(), 13)
                && checkStringNotNeeded(client.getPhone(), 12)
                && checkStringNotNeeded(client.getEmail(), 50)
                && checkStringNotNeeded(client.getPassword(), 255)
                && checkStringNotNeeded(client.getComments(), 100);
    }

    public static List<Boolean> checkClientCheckList(ClientsModel client, Date startDate, Date endDate) {
        List<Boolean> checks = new ArrayList<Boolean>();
        checks.add(checkString(client.getName(), 20));
        checks.add(checkString(client.getLastName(), 50));
        checks.add(checkString(client.getCity(), 30));
        checks.add(checkString(client.getZipCode(), 15));
        checks.add(checkString(client.getStreet(), 30));
        checks.add(checkString(client.getHouseNumber(), 15));
        checks.add(checkIntNotNeeded(client.getLocalNumber(), 11));
        checks.add(checkStringNotNeeded(client.getNipNumber(), 13));
        checks.add(checkStringNotNeeded(client.getPhone(), 12));
        checks.add(checkStringNotNeeded(client.getComments(), 100));
        checks.add(isValidEmailAddress(client.getEmail()));
        checks.add(checkDate(startDate));
        checks.add(checkDate(endDate));

        return checks;
    }
    
    public static List<Boolean> checkEmployeeCheckList(EmployeesModel emp){
         List<Boolean> checks = new ArrayList<Boolean>();
         checks.add(checkString(emp.getSurname(), 50));
         checks.add(checkString(emp.getFirstname(), 20));
         checks.add(checkPesel(emp.getPeselNumber()));
         checks.add(checkString(emp.getCity(), 30));
         checks.add(checkString(emp.getZipCode(), 15));
         checks.add(checkString(emp.getStreet(), 30));
         checks.add(checkString(emp.getHouseNumber(), 15));
         checks.add(checkIntNotNeeded(emp.getLocalNumber(), 11));
         checks.add(checkJobType(emp.getJobType()));
         checks.add(Boolean.TRUE);
         checks.add(Boolean.TRUE);
         checks.add(checkStringNotNeeded(emp.getPhone(), 12));
         checks.add(checkSalary(emp.getSalary()));
         checks.add(isValidEmailAddress(emp.getEmail()));
         checks.add(checkString(emp.getPassword(), 255));
         checks.add(checkStringNotNeeded(emp.getComments(), 100));
         
         return checks;
    }

    public static boolean checkCar(CarsModel car) {
        if (checkNull(car)) {
            return false;
        }
        return checkString(car.getNumberPlate(), 10)
                && checkString(car.getMake(), 20)
                && checkString(car.getModel(), 50)
                && checkCarType(car.getCarType())
                && checkStringNotNeeded(car.getComments(), 100);
    }

    public static List<Boolean> checkCarCheckList(CarsModel car) {
        List<Boolean> checks = new ArrayList<Boolean>();
        checks.add(checkString(car.getNumberPlate(), 10));
        checks.add(checkString(car.getMake(), 20));
        checks.add(checkString(car.getModel(), 50));
        checks.add(checkCarType(car.getCarType()));
        checks.add(checkStringNotNeeded(car.getComments(), 100));

        return checks;
    }

    public static boolean checkParkingSpace(ParkingspacesModel parkingSpace) {
        if (checkNull(parkingSpace)) {
            return false;
        }
        return checkSpaceType(parkingSpace.getType())
                && checkStatus(parkingSpace.getStatus());
    }

    public static boolean checkTarrif(TarrifsModel tarrif) {
        if (checkNull(tarrif)) {
            return false;
        }
        return checkString(tarrif.getName(), 30)
                && checkDate(tarrif.getIssueDate())
                && checkDate(tarrif.getEndDate())
                && checkString(tarrif.getDurationTime(), 7)
                && checkSalary(tarrif.getRank())
                && checkCarType(tarrif.getCarType())
                && checkStringNotNeeded(tarrif.getComments(), 100);
    }

    public static List<Boolean> checkTarrifCheckList(TarrifsModel tarrif) {
        List<Boolean> checks = new ArrayList<Boolean>();
        checks.add(checkString(tarrif.getName(), 30));
        checks.add(checkDate(tarrif.getIssueDate()));
        checks.add(checkDate(tarrif.getEndDate()));
        checks.add(checkString(tarrif.getDurationTime(), 7));
        checks.add(checkSalary(tarrif.getRank()));
        checks.add(checkCarType(tarrif.getCarType()));
        checks.add(checkStringNotNeeded(tarrif.getComments(), 100));

        return checks;
    }
    
    public static boolean checkDataFormat(String data){
        boolean ok=true;
        
        if(checkNull(data)){
            ok=false;
        }
        else{
            try{
                Date dd = java.sql.Date.valueOf(data);
            }
            catch(Exception e){
                ok=false;
            }
        }
    
        return ok;
    }
    
    public static boolean checkMoneyFormat(String m){
        boolean ok=true;
        
        if(checkNull(m)){
            ok=false;
        }
        else{
            try{
                Double.parseDouble(m);
            }
            catch(Exception e){
                ok=false;
            }
        }
    
        return ok;
    }

    public static boolean checkAccountingData(AccountingdataModel accountingData) {
        if (checkNull(accountingData)) {
            return false;
        }
        return checkString(accountingData.getName(), 255)
                && checkString(accountingData.getCity(), 30)
                && checkString(accountingData.getZipNumber(), 15)
                && checkString(accountingData.getStreet(), 30)
                && checkString(accountingData.getHouseNumber(), 15)
                && checkStringNotNeeded(accountingData.getLocalNumber(), 15)
                && checkStringNotNeeded(accountingData.getNipNumber(), 13)
                && checkStringNotNeeded(accountingData.getPhone(), 15)
                && checkPayerType(accountingData.getPayerType())
                && checkStringNotNeeded(accountingData.getComments(), 100);
    }

    public static List<Boolean> checkAccountingDataCheckList(AccountingdataModel accountingData) {
        List<Boolean> checks = new ArrayList<Boolean>();
        checks.add(checkString(accountingData.getName(), 255));
        checks.add(checkString(accountingData.getCity(), 30));
        checks.add(checkString(accountingData.getZipNumber(), 15));
        checks.add(checkString(accountingData.getStreet(), 30));
        checks.add(checkString(accountingData.getHouseNumber(), 15));
        checks.add(checkStringNotNeeded(accountingData.getLocalNumber(), 15));
        checks.add(checkStringNotNeeded(accountingData.getNipNumber(), 13));
        checks.add(checkStringNotNeeded(accountingData.getPhone(), 15));
        checks.add(checkPayerType(accountingData.getPayerType()));
        checks.add(checkStringNotNeeded(accountingData.getComments(), 100));

        return checks;
    }

    public static boolean checkServices(ServicesModel service) {
        if (checkNull(service)) {
            return false;
        }
        return checkDate(service.getModificationDate());
    }

    public static boolean checkReceivables(ReceivablesModel receivable) {
        if (checkNull(receivable)) {
            return false;
        }
        return checkSalary(receivable.getAmount())
                && checkDate(receivable.getCreationDate())
                && checkDate(receivable.getPayDeadline());
    }

    public static boolean checkPayments(PaymentsModel payment) {
        if (checkNull(payment)) {
            return false;
        }
        return checkDate(payment.getPaymentDate())
                && checkPaymentType(payment.getPaymentForm());
    }

    public static boolean checkPark(ParksModel park) {
        if (checkNull(park)) {
            return false;
        }
        return checkParkType(park.getType())
                && checkDate(park.getParkDate());
    }

    public static boolean checkPasses(ParkingpassesModel pass) {
        if (checkNull(pass)) {
            return false;
        }
        return checkDate(pass.getDateIssue())
                && checkDate(pass.getExpirationDate())
                & checkPassType(pass.getPassType());
    }

    public static boolean checkPassesrecord(PassesrecordsModel passesRecords) {
        if (checkNull(passesRecords)) {
            return false;
        }
        return checkDate(passesRecords.getAddingDate());
    }

    public static boolean checkId(Integer id) {
        if (checkNull(id)) {
            return false;
        }
        return id >= 0;
    }

    private static boolean checkString(String toCheck, int maxLength) {
        if (checkNull(toCheck)) {
            return false;
        }
        if (toCheck.length() > maxLength || toCheck.length() < 1) {
            return false;
        }
        return true;
    }

    private static boolean checkStringNotNeeded(String toCheck, int maxLength) {
        if (checkNull(toCheck)) {
            return true;
        }
        if (toCheck.length() > maxLength) {
            return false;
        }
        return true;
    }

    private static boolean checkIntNotNeeded(Integer number, int length) {
        if (checkNull(number)) {
            return true;
        }
        if (number > Math.pow(10, length) || number < 1) {
            return false;
        }
        return true;
    }

    private static boolean checkNull(Object o) {
        if (o == null) {
            return true;
        }
        return false;
    }

    public static boolean checkPesel(String pesel) {
        long peselNumber;
        try {
            peselNumber = Long.parseLong(pesel);
        } catch (NumberFormatException ex) {
         //   System.out.println("Cannot parse PESEL number " + ex);
            return false;
        }
        if (checkNull(pesel)) {
            return false;
        }
        return peselNumber > 0;
    }

    private static boolean checkDate(Date date) {
        if (checkNull(date)) {
            return false;
        }
        return true;
    }

    private static boolean checkSalary(double salary) {

        return salary > 0;
    }

    private static boolean checkCarType(String carType) {
        if (checkNull(carType)) {
            return false;
        }
        return carType.equals("Personal") || carType.equals("Van") || carType.equals("Motorcycle") || carType.equals("Trailer");
    }
    
     private static boolean checkJobType(String jobType) {
        if (checkNull(jobType)) {
            return false;
        }
        return jobType.equals("admin") || jobType.equals("bookkeeper") || jobType.equals("manager") || jobType.equals("porter");
    }
    
    private static boolean checkSpaceType(String spaceType) {
        if (checkNull(spaceType)) {
            return false;
        }
        return spaceType.equals("Personal") || spaceType.equals("Van") || spaceType.equals("Motorcycle") || spaceType.equals("Trailer") || spaceType.equals("Special") || spaceType.equals("All");
    }

    private static boolean checkStatus(String status) {
        if (checkNull(status)) {
            return false;
        }
        return status.equals("Free") || status.equals("Occupied") || status.equals("Disabled");
    }

    private static boolean checkPayerType(String payerType) {
        if (checkNull(payerType)) {
            return false;
        }
        return payerType.equals("Company") || payerType.equals("PrivatePerson");
    }

    private static boolean checkPaymentType(String paymentType) {
        if (checkNull(paymentType)) {
            return false;
        }
        return paymentType.equals("Cash") || paymentType.equals("CreditCard") || paymentType.equals("Transfer");
    }

    private static boolean checkParkType(String parkType) {
        if (checkNull(parkType)) {
            return false;
        }
        return parkType.equals("Entry") || parkType.equals("Exit");
    }

    private static boolean checkPassType(String passType) {
        if (checkNull(passType)) {
            return false;
        }
        return passType.equals("Permanent") || passType.equals("Temporary");
    }

    public static boolean isValidEmailAddress(String email) {
        if(email == null) {
            return true;
        }
        if(email.isEmpty()){
            return true;
        }
        pattern = Pattern.compile(EMAIL_PATTERN);
        matcher = pattern.matcher(email);
        return matcher.matches();
    }
}
